home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / KPlib 1.3.5 / KPString.h < prev    next >
Text File  |  1995-12-17  |  9KB  |  255 lines

  1. // A module of KPlib v1.3.5.
  2. // Written by Keith Pomakis during the summer of 1994.
  3. // Released to the public domain on October 10, 1994.
  4.  
  5. #ifndef KP_STRING_DEFINED
  6. #define KP_STRING_DEFINED
  7.  
  8. #include <iostream.h>
  9. #include <strstream.h>
  10. #include <string.h>
  11. #include "KPbasic.h"
  12.  
  13. // This class uses reference counting and copy-on-write semantics to insure
  14. // that it as efficient as possible.
  15.  
  16. // All indexes are zero-based.  For all functions that accept an index, a
  17. // negative index specifies an index from the right of the string.  Also,
  18. // for all functions that accept a length, a length of -1 specifies the rest
  19. // of the string.
  20.  
  21. // "KPList.h" is included further on down to insure that it isn't defined
  22. // before KPString, so that KPList<KPString> will be considered a complete
  23. // type in the following definition of KPString.  This is probably a
  24. // g++-specific problem.
  25.  
  26. template <class Element> class KPList;
  27.  
  28. class KPString {
  29.         friend istream &operator>>(istream &stream, KPString &s);
  30.         inline friend ostream &operator<<(ostream &stream, const KPString &s);
  31.         friend KPString operator+(const char *s1, const KPString &s2);
  32.         inline friend bool operator==(const char *s1, const KPString &s2);
  33.         inline friend bool operator<(const char *s1, const KPString &s2);
  34.         inline friend bool operator<=(const char *s1, const KPString &s2);
  35.         inline friend bool operator>(const char *s1, const KPString &s2);
  36.         inline friend bool operator>=(const char *s1, const KPString &s2);
  37.         inline friend bool operator!=(const char *s1, const KPString &s2);
  38.         inline friend void swap(KPString &s1, KPString &s2);
  39.     public:
  40.         KPString();
  41.         KPString(const KPString &s);
  42.         KPString(const char *s);
  43.         KPString(char c, int n = 1);
  44.         ~KPString();
  45.         operator const char *() const;
  46.         char &operator[](int index);
  47.         char operator[](int index) const;
  48.         KPString &operator=(const KPString &s);
  49.         KPString &operator=(const char *s);
  50.         KPString operator+(const KPString &s) const;
  51.         KPString operator+(const char *s) const;
  52.         bool operator==(const KPString &s) const;
  53.         bool operator==(const char *s) const;
  54.         bool operator<(const KPString &s) const;
  55.         bool operator<(const char *s) const;
  56.         bool operator<=(const KPString &s) const;
  57.         bool operator<=(const char *s) const;
  58.         bool operator>(const KPString &s) const;
  59.         bool operator>(const char *s) const;
  60.         bool operator>=(const KPString &s) const;
  61.         bool operator>=(const char *s) const;
  62.         bool operator!=(const KPString &s) const;
  63.         bool operator!=(const char *s) const;
  64.         KPString &operator+=(const KPString &s);
  65.         KPString &operator+=(const char *s);
  66.         int length() const;
  67.         bool is_empty() const;
  68.         bool is_whitespace() const;
  69.         KPString substr(int index = 0, int len = -1) const;
  70.         KPString copy() const;
  71.         KPString &cut(int index = 0, int len = -1);
  72.         KPString &replace_substr(const KPString &s, int index = 0, int len=-1);
  73.         KPString &replace_substr(const char *s, int index = 0, int len = -1);
  74.         KPString &insert(const KPString &s, int index = 0);
  75.         KPString &insert(const char *s, int index = 0);
  76.         KPString &to_upper();
  77.         KPString &to_lower();
  78.         KPString &clear();
  79.         int index_of(const KPString &s, int start_index = 0) const;
  80.         int index_of(const char *s, int start_index = 0) const;
  81.         int index_of(char c, int start_index = 0) const;
  82.         bool contains(const KPString &s) const;
  83.         bool contains(const char *s) const;
  84.         bool contains(char c) const;
  85.         KPList<KPString> tokens(const char *separators=" \t\n\v\r\f") const;
  86.         KPList<KPString> tokens(char separator) const;
  87.         KPString &read_line(istream &stream);
  88.         KPString &
  89.             read_token(istream &stream, const char *separators=" \t\n\v\r\f");
  90.  
  91.         static const int max_token_size;
  92.         static const int max_line_size;
  93.  
  94.     protected:
  95.         static void invalid_args_error(const char *fname);
  96.         static void invalid_index_error(const char *fname);
  97.         class Data {
  98.             public:
  99.                 Data(): ref_count(0), length(0) { chars[0] = '\0'; }
  100.                 unsigned int ref_count;
  101.                 int length;
  102.                 char chars[1];
  103.         };
  104.         static Data *new_data(int length);
  105.         void replace_data(int length);
  106.         void replace_data(Data *data);
  107.         void make_unique();
  108.         char *chars();
  109.         const char *chars() const;
  110.     protected:
  111.         Data *my_data;
  112.         static Data null_data;
  113. };
  114.  
  115. /***************************************************************************/
  116.  
  117. #include "KPList.h"
  118.  
  119. inline char *KPString::chars()
  120. { return my_data->chars; }
  121.  
  122. inline const char *KPString::chars() const
  123. { return my_data->chars; }
  124.  
  125. inline ostream &operator<<(ostream &stream, const KPString &s)
  126. { stream << s.chars(); return stream; }
  127.  
  128. inline bool operator==(const char *s1, const KPString &s2)
  129. { return (strcmp(s1, s2.chars()) == 0); }
  130.  
  131. inline bool operator<(const char *s1, const KPString &s2)
  132. { return (strcmp(s1, s2.chars()) < 0); }
  133.  
  134. inline bool operator<=(const char *s1, const KPString &s2)
  135. { return (strcmp(s1, s2.chars()) <= 0); }
  136.  
  137. inline bool operator>(const char *s1, const KPString &s2)
  138. { return (strcmp(s1, s2.chars()) > 0); }
  139.  
  140. inline bool operator>=(const char *s1, const KPString &s2)
  141. { return (strcmp(s1, s2.chars()) >= 0); }
  142.  
  143. inline bool operator!=(const char *s1, const KPString &s2)
  144. { return (strcmp(s1, s2.chars()) != 0); }
  145.  
  146. inline void swap(KPString &s1, KPString &s2)
  147. { KPString::Data *tmp = s1.my_data; s1.my_data = s2.my_data; s2.my_data = tmp; }
  148.  
  149. inline KPString::KPString(): my_data(&null_data)
  150. { /* do nothing */ }
  151.  
  152. inline KPString::KPString(const KPString &s): my_data(&null_data)
  153. { replace_data(s.my_data); }
  154.  
  155. inline KPString::KPString(const char *s): my_data(&null_data)
  156. { const int length = ::strlen(s); replace_data(length);
  157.   ::memcpy(chars(), s, length); }
  158.  
  159. inline KPString::KPString(char c, int n): my_data(&null_data)
  160. { replace_data(n); ::memset(chars(), c, n); }
  161.  
  162. inline KPString::~KPString()
  163. { if (my_data != &null_data && --my_data->ref_count == 0) free(my_data); }
  164.  
  165. inline int KPString::length() const
  166. { return my_data->length; }
  167.  
  168. inline KPString::operator const char *() const
  169. { return my_data->chars; }
  170.  
  171. inline char &KPString::operator[](int index)
  172. { if (index < 0) index += length();
  173.   if (index < 0 || index >= length()) invalid_index_error("operator[]");
  174.   make_unique(); return chars()[index]; }
  175.  
  176. inline char KPString::operator[](int index) const
  177. { if (index < 0) index += length();
  178.   if (index < 0 || index >= length()) invalid_index_error("operator[]");
  179.   return chars()[index]; }
  180.  
  181. inline KPString &KPString::operator=(const KPString &s)
  182. { replace_data(s.my_data); return *this; }
  183.  
  184. inline KPString &KPString::operator=(const char *s)
  185. { const int length = ::strlen(s); replace_data(length);
  186.   ::memcpy(chars(), s, length); return *this; }
  187.  
  188.  
  189. inline bool KPString::operator==(const KPString &s) const
  190. { return (length() == s.length()) &&
  191.          (memcmp(chars(), s.chars(), length()) == 0); }
  192.  
  193. inline bool KPString::operator==(const char *s) const
  194. { return (strcmp(chars(), s) == 0); }
  195.  
  196. inline bool KPString::operator<(const KPString &s) const
  197. { return (strcmp(chars(), s.chars()) < 0); }
  198.  
  199. inline bool KPString::operator<(const char *s) const
  200. { return (strcmp(chars(), s) < 0); }
  201.  
  202. inline bool KPString::operator<=(const KPString &s) const
  203. { return (strcmp(chars(), s.chars()) <= 0); }
  204.  
  205. inline bool KPString::operator<=(const char *s) const
  206. { return (strcmp(chars(), s) <= 0); }
  207.  
  208. inline bool KPString::operator>(const KPString &s) const
  209. { return (strcmp(chars(), s.chars()) > 0); }
  210.  
  211. inline bool KPString::operator>(const char *s) const
  212. { return (strcmp(chars(), s) > 0); }
  213.  
  214. inline bool KPString::operator>=(const KPString &s) const
  215. { return (strcmp(chars(), s.chars()) >= 0); }
  216.  
  217. inline bool KPString::operator>=(const char *s) const
  218. { return (strcmp(chars(), s) >= 0); }
  219.  
  220. inline bool KPString::operator!=(const KPString &s) const
  221. { return (length() != s.length()) ||
  222.          (memcmp(chars(), s.chars(), length()) != 0); }
  223.  
  224. inline bool KPString::operator!=(const char *s) const
  225. { return (strcmp(chars(), s) != 0); }
  226.  
  227. inline KPString &KPString::operator+=(const KPString &s)
  228. { *this = *this + s; return *this; }
  229.  
  230. inline KPString &KPString::operator+=(const char *s)
  231. { *this = *this + s; return *this; }
  232.  
  233. inline bool KPString::is_empty() const
  234. { return my_data == &null_data; }
  235.  
  236. inline KPString KPString::copy() const
  237. { KPString newstring(*this); return newstring; }
  238.  
  239. inline KPString &KPString::clear()
  240. { replace_data(0); return *this; }
  241.  
  242. inline int KPString::index_of(const KPString &s, int start_index) const
  243. { return index_of(s.chars(), start_index); }
  244.  
  245. inline bool KPString::contains(const KPString &s) const
  246. { return (index_of(s, 0) >= 0); }
  247.  
  248. inline bool KPString::contains(const char *s) const
  249. { return (index_of(s, 0) >= 0); }
  250.  
  251. inline bool KPString::contains(char c) const
  252. { return (index_of(c, 0) >= 0); }
  253.  
  254. #endif /* KP_STRING_DEFINED */
  255.